import 'dart:math';

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter_flappy_bird/background.dart';
import 'package:flutter_flappy_bird/pipes.dart';
import 'package:flutter_flappy_bird/score.dart';
import 'package:flutter_flappy_bird/start_button.dart';
import 'package:flutter_flappy_bird/title.dart';

import 'bird.dart';
import 'game_over.dart';
import 'land.dart';

class FlappyBirdGame extends FlameGame with TapDetector {
  late Component backgroundComponent;
  late Component landComponent;
  late Component birdComponent;
  late Component titleComponent;
  late Component startButtonComponent;
  late Component gameOverComponent;
  late Component scoreComponent;
  List<Component> pipesComponents = [];
  int score = 0;

  @override
  Future<void>? onLoad() async {
    backgroundComponent = BackgroundComponent(size);
    backgroundComponent.priority = 0;
    birdComponent = BirdComponent(size, _onBirdFlyStatusCallback);
    birdComponent.priority = 4;
    landComponent = LandComponent(size, birdComponent as BirdComponent);
    landComponent.priority = 1;
    titleComponent = TitleComponent(size, birdComponent as BirdComponent);
    titleComponent.priority = 3;
    startButtonComponent =
        StartButtonComponent(size, birdComponent as BirdComponent);
    startButtonComponent.priority = 3;
    gameOverComponent = GameOverComponent(size, birdComponent as BirdComponent);
    gameOverComponent.priority = 3;
    scoreComponent = ScoreComponent(size, birdComponent as BirdComponent);
    scoreComponent.priority = 3;
    await add(backgroundComponent);
    await add(landComponent);
    await add(birdComponent);
    await add(titleComponent);
    await add(startButtonComponent);
    return super.onLoad();
  }

  // 动态添加管道
  void _addNewPipeGroup() {
    int upPipeHeight = 80 + Random().nextInt(size.y ~/ 2 - 96);
    Component pipeUpComponent = PipeUpComponent(upPipeHeight.toDouble(), () {
      _addNewPipeGroup();
    }, birdComponent as BirdComponent, _onBirdFlyPassedCallback);
    int flySpace = 80 + Random().nextInt(50);
    int downPipeHeight = size.y.toInt() - 96 - upPipeHeight - flySpace;
    Component pipeDownComponent = PipeDownComponent(
        downPipeHeight.toDouble(), birdComponent as BirdComponent);
    pipeUpComponent.priority = 1;
    pipeDownComponent.priority = 1;
    pipesComponents.add(pipeUpComponent);
    pipesComponents.add(pipeDownComponent);
    add(pipeUpComponent);
    add(pipeDownComponent);
  }

  // 小鸟飞行状态改变回调
  void _onBirdFlyStatusCallback(int status) {
    if (status == BirdComponent.statusGameOver) {
      if (!contains(gameOverComponent) &&
          gameOverComponent.findParent() == null) {
        add(gameOverComponent);
      }
    }
  }

  // 得分回调
  void _onBirdFlyPassedCallback() {
    score++;
    (scoreComponent as ScoreComponent).setScore(score);
  }

  @override
  void onTapDown(TapDownInfo info) {
    super.onTapDown(info);
    // 未启动游戏时，启动游戏，并触发一次向上飞的动作
    if ((birdComponent as BirdComponent).getCurrentStatus() ==
        BirdComponent.statusBeforeGame) {
      (birdComponent as BirdComponent).changeStatus(BirdComponent.statusFlying);
      (birdComponent as BirdComponent).flyUp();
      _addNewPipeGroup();
      add(scoreComponent);
      score = 0;
      (scoreComponent as ScoreComponent).setScore(score);
      // 游戏中，触发一次向上飞的动作
    } else if ((birdComponent as BirdComponent).getCurrentStatus() ==
        BirdComponent.statusFlying) {
      (birdComponent as BirdComponent).flyUp();
      // 游戏结束，再次点击则回到初始状态
    } else if ((birdComponent as BirdComponent).getCurrentStatus() ==
        BirdComponent.statusGameOver) {
      for (int i = 0; i < pipesComponents.length; i++) {
        try {
          remove(pipesComponents[i]);
        } catch (_) {}
      }
      pipesComponents.clear();
      (birdComponent as BirdComponent).reset();
      add(titleComponent);
      add(startButtonComponent);
    }
  }
}
